/*
** ############################################################################
**     Project   : osdee - Operative Systems Design for Embedded Envrionments
**     File      : Gpt.c
**     Revision  ; 1.0
**     Abstract  :
**         GPT module implementation.
**     Processor : MC9S12XEP100CVL
**     Version   : Component 01.042, Driver 01.05, CPU db: 3.00.036
**     Datasheet : MC9S12XEP100 Rev. 1.19 12/2008
**
**     Copyright : 2014 Fernando Rodriguez, Open source with out any responsability.
**
**     Note      : For a direct use of PIT (Periodic Interrupt Timers) 
**               : with out GPT (General Purpose Timer), see example code 
**               : at the file end. However note that using GPT is safer an easier.
**     
**     mail      : frr@gmail.com
** ############################################################################
*/

#include "Gpt.h"

/*
** ===================================================================
**     Description :
**         Internal functions declarations.
** ===================================================================
*/
void Mcu_vGPT_LoadConfiguration(const tsGPT_Configuration* tGPT_Configuration);
BOOL Mcu_boGTP_VerifyChannelValues(tsPIT_Channel* tChannel);

/*
** ===================================================================
**     Function    :  Gpt_Init
**
**     Description :
**         Initializes the GPT module with an specified Configuration.
**     Parameter   : 
**         -tGPT_Configuration: Contains GPT Configuration, could also
**                              be NULL, in such case only general GPT 
**                              initialization is performed.
** ===================================================================
*/
void Gpt_Init(const tsGPT_Configuration* tGPT_Configuration)
{
  /* Basic PIT initialization should be performed */
  Mcu_vPIT_General_Initialize();
  
  if(tGPT_Configuration != NULL && tGPT_Configuration->boLoad_GPT_Configuration)
  {
    Mcu_vGPT_LoadConfiguration(tGPT_Configuration);
  }  
}

/*
** ===================================================================
**     Function     :  Gpt_StartTimer
**
**     Description  :
**         Initializes the GPT module with an specified Configuration.
**     Parameter    : 
**         -tChannel  : Channel atomic info. 
**                      Allows to define specific channel properties
**                      like Callback!.
**         -u32Period : Channel Period.
** ===================================================================
*/
void Gpt_StartTimer(tsPIT_Channel* tChannel, UINT32 u32Period)
{ 
  Mcu_vPTI_Stop(tChannel);
  
  if(u32Period <= PIT_HIGHRES_MAX_VALUE && u32Period >= PIT_HIGHRES_MIN_VALUE)
  {
    tChannel->tType = PIT_Type_HihgResolution;
  }
  else if (u32Period <= PIT_HIGHPERIOD_MAX_VALUE && u32Period >= PIT_HIGHPERIOD_MIN_VALUE)
  {
    tChannel->tType = PIT_Type_HihgPeriod;	
  }
  else
  {
    /* Error: Unsuported Period length */;
    return;
  }
  
  tChannel->u32Period = u32Period; 	
  
  if(Mcu_boGTP_VerifyChannelValues(tChannel))
  {
    Mcu_vPTI_Initialize(tChannel);

    Mcu_vPTI_Start(tChannel);

    Mcu_vPTI_Enable(tChannel);
  }
}

/*
** ===================================================================
**     Function     :  Gpt_StartTimer
**
**     Description  :
**         Initializes the GPT module with an specified Configuration.
**     Parameter    : 
**         -tChannelId : Channel id to be started.
**         -u32Period  : Channel Period.
** ===================================================================
*/
void Gpt_StartTimerById(tePIT_Channel_Id tChannelId, UINT32 u32Period)
{
  tsPIT_Channel* tChannel = &mal_mcu_tGPT_configuration.atChannels[tChannelId].tChannel;
  
  Gpt_StartTimer(tChannel, u32Period);
}

/*
** ===================================================================
**     Function     :  Gpt_StopTimer
**
**     Description  :
**         Initializes the GPT module with an specified Configuration.
**     Parameter    : 
**         -tChannelId : Channel id to be started.
**         -u32Period  : Channel Period.
** ===================================================================
*/
void Gpt_StopTimer(tePIT_Channel_Id tChannelId)
{
  tsPIT_Channel* tChannel = &mal_mcu_tGPT_configuration.atChannels[tChannelId].tChannel;
  
  Mcu_vPTI_Stop(tChannel);
}

/*
** ===================================================================
**     Function     :  Gpt_EnableNotification
**
**     Description  :
**         Enables GPT Channel notifications (interrupts).
**     Parameter    : 
**         -tChannelId : Channel id to be started.
** ===================================================================
*/
void Gpt_EnableNotification(tePIT_Channel_Id tChannelId)
{
  tsPIT_Channel* tChannel = &mal_mcu_tGPT_configuration.atChannels[tChannelId].tChannel;
  
  Mcu_vPTI_Enable(tChannel);
}

/*
** ===================================================================
**     Function     :  Gpt_DisableNotification
**
**     Description  :
**         Enables GPT Channel notifications (interrupts).
**     Parameter    : 
**         -tChannelId : Channel id to be started.
** ===================================================================
*/
void Gpt_DisableNotification(tePIT_Channel_Id tChannelId)
{
  tsPIT_Channel* tChannel = &mal_mcu_tGPT_configuration.atChannels[tChannelId].tChannel;
  
  Mcu_vPTI_Disable(tChannel);
}

/*
** ===================================================================
**     Description :
**         Internal functions declarations.
** ===================================================================
*/

/*
** ===================================================================
**     Function    :  Mcu_vGPT_LoadConfiguration
**
**     Description :
**         Loads GPT Configuration.
**     Parameter   : 
**         -tGPT_Configuration: Contains GPT Configuration
** ===================================================================
*/
void Mcu_vGPT_LoadConfiguration(const tsGPT_Configuration* tGPT_Configuration)
{
   UINT8 u8ChannelId = 0;
   
   while(u8ChannelId < PIT_SUPPORTED_CHANNELS)
   {
     if(tGPT_Configuration->atChannels[u8ChannelId].boInitialize &&
        Mcu_boGTP_VerifyChannelValues(&tGPT_Configuration->atChannels[u8ChannelId].tChannel))
     {
       Mcu_vPTI_Initialize(&tGPT_Configuration->atChannels[u8ChannelId].tChannel);
       
       if(tGPT_Configuration->atChannels[u8ChannelId].boStart)
       {
         Mcu_vPTI_Start(&tGPT_Configuration->atChannels[u8ChannelId].tChannel);
       }
       
       if(tGPT_Configuration->atChannels[u8ChannelId].boEnabled)
       {
         Mcu_vPTI_Enable(&tGPT_Configuration->atChannels[u8ChannelId].tChannel);
       }
     }
     
     u8ChannelId++;
   }
}

/*
** ===================================================================
**     Function    :  Mcu_boGTP_VerifyChannelValues
**
**     Description :
**         Verifies that channel Period is in the limits according
**         with the Channel Type configured..
**     Parameter   : 
**         -tGPT_Configuration: Contains GPT Configuration
** ===================================================================
*/
BOOL Mcu_boGTP_VerifyChannelValues(tsPIT_Channel* tChannel)
{
  BOOL boRet = FALSE;
  
  if(tChannel->tType == PIT_Type_HihgResolution)
  {
    boRet = tChannel->u32Period >= PIT_HIGHRES_MIN_VALUE &&
            tChannel->u32Period <= PIT_HIGHRES_MAX_VALUE;	
  }
  else
  {
    boRet = tChannel->u32Period >= PIT_HIGHPERIOD_MIN_VALUE &&
            tChannel->u32Period <= PIT_HIGHPERIOD_MAX_VALUE;
  }
  
  return boRet;
}


/*
** ===================================================================
**     Function    :  Mcu_GPT_ChannelX_Callback
**
**     Description :
**         GPT Channels callbacks implementations.
**         User can define his/her own callback implementation
**         for any channel, using this prototypes or maybe 
**         any other function linked to the channel.
** ===================================================================
*/
void Mcu_GPT_Channel0_Callback(void)
{
  extern UINT16 m_tSchm_Counter;
  m_tSchm_Counter++;
  (void)ActivateTask(OS_Task_2);
  
}
void Mcu_GPT_Channel1_Callback(void)
{
}
void Mcu_GPT_Channel2_Callback(void)
{
}
void Mcu_GPT_Channel3_Callback(void)
{
}
void Mcu_GPT_Channel4_Callback(void)
{
}
void Mcu_GPT_Channel5_Callback(void)
{
}
void Mcu_GPT_Channel6_Callback(void)
{
}
void Mcu_GPT_Channel7_Callback(void)
{
}
/*
** ===================================================================
**     Abstract    :  Example of direct use of PIT
**
**     Description :
**         The following code shows another alternative to
**         use timers wihtout GPT, however using GPT is safer and esaier.
** ===================================================================
*/
//
//tsPIT_Channel apl_PIT0; /* Create an PIT Channel configuration */
//
//void apl_vStartPIT0()   /* User function to start using the PIT Timmer */
//{
//  
// apl_PIT0.tChannel_Id = PIT0;
// apl_PIT0.u32Period = 781;
// apl_PIT0.tType = PIT_Type_HihgResolution;
// apl_PIT0.tCallback = vfnPIT_channel0_Callback;
// 
// Mcu_vPIT_General_Initialize();
// 
// Mcu_vPTI_Initialize(apl_PIT0);
// Mcu_vPTI_Start(apl_PIT0);
// 	
//}
//
//void vfnPIT_channel0_Callback(void)  /* A Callback should be provided */
//{ 
//  Mcu_vPTI_Start(apl_PIT0);          /* Optional if only one timmer run is required */
//  
//  PORTA_PA0 = ~PORTA_PA0;
//}
